#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include "ring.h"
#include <assert.h>

#define FREE_FLAGS 0x88
#define ALLOCED_FLAGS 0x55
typedef struct buff_mng{
	RING_MNG *buff_list;
}BUFF_MNG;
typedef struct memhead
{
	uint8_t alloced;
	uint8_t reserv[3];
}MEMHEAD;
BUFF_MNG my_buffer_alloc;

int init_pkt_buff(int maxnum,int ptksize)
{
	uint8_t *tmpbuff = NULL;
	MEMHEAD *head = NULL;
	RING_DESC ringentry;
	int i = 0;
	memset(&my_buffer_alloc,0,sizeof(BUFF_MNG));

	my_buffer_alloc.buff_list = alloc_ring(maxnum,0);
	for (i = 0;i < maxnum;i++)
	{
		tmpbuff = malloc(ptksize+sizeof(MEMHEAD));
		if (tmpbuff == NULL)
			return -1;
		head = (MEMHEAD*)tmpbuff;
		head->alloced = FREE_FLAGS;
		ringentry.address = (uint32_t)tmpbuff;
		add_entry_to_ring(&ringentry,my_buffer_alloc.buff_list);
	}
	
	return 0;
}

uint8_t *malloc_pkt_buffer(void)
{
#if 1
	int ret = 0;
	RING_DESC ringentry;
	MEMHEAD *head = NULL;
	ret = get_entry_from_ring(&ringentry,my_buffer_alloc.buff_list);
	if (ret != 0)
	{
		printf("malloc_pkt_buffer error\n");
		return NULL;
	}
	head = (MEMHEAD*)ringentry.address;
	head->alloced = ALLOCED_FLAGS;
	return (uint8_t*)((uint8_t*)head+sizeof(MEMHEAD));
#else
	return (uint8_t*)malloc(1560);
#endif
}

int free_pkt_buffer(uint8_t *buff)
{
#if 1
	int ret = 0;
	RING_DESC ringentry;
	MEMHEAD *head = (MEMHEAD*)((uint8_t*)buff-sizeof(MEMHEAD));
	if (head->alloced != ALLOCED_FLAGS)
	{
		printf("free_pkt_buffer:invalid ptk %p 0x%x!=0x%x\n",buff,head->alloced,ALLOCED_FLAGS);
		*(uint8_t*)0x0 = 1;
		return -1;
	}
	ringentry.address = (uint32_t)((uint8_t*)buff-sizeof(MEMHEAD));
	
	ret = add_entry_to_ring(&ringentry,my_buffer_alloc.buff_list);
	if (ret != 0)
	{
		return -1;
	}
	head->alloced = FREE_FLAGS;
#else
	free(buff);
#endif
	return 0;
}

int get_free_pkt()
{
	return my_buffer_alloc.buff_list->usednums;
}


